<?php

use Phinx\Migration\AbstractMigration;

class FillUserAuthenticationCustomFieldsData extends AbstractMigration
{
    /**
     * 获取所有模块数据
     * @return array
     */
    public function getAllModuleData()
    {
        $sql = 'select * from module';
        $result = $this->query($sql);
        $info = array();
        foreach ($result as $key => $val) {
            $info[$val['code']] = $val;
        }
        return $info;
    }


    /**
     * 获取所有属性数据
     * @return array
     */
    public function getAllAttributeData()
    {
        $sql = 'select * from attribute';
        $result = $this->query($sql);
        $info = array();
        foreach ($result as $key => $val) {
            $info[$val['code']] = $val;
        }
        return $info;
    }

    /**
     * 判断当前字段是否为必须
     * @param $field
     * @return string
     */
    public function checkFieldRequire($field)
    {
        if (in_array($field, ['name', 'phone', 'password', 'value', 'ptype', 'status', 'man_hour', 'type', 'attribute_value'])) {
            return 'yes';
        }

        if (strpos($field, '_id')) {
            return 'yes';
        }

        return 'no';
    }

    /**
     * 判断当前字段是否能编辑
     * @param $field
     * @return string
     */
    public function checkFieldEdit($field)
    {
        if (in_array($field, ['id', 'uuid', 'created_by', 'created', 'json', 'is_horizontal'])) {
            return 'deny';
        }

        if (strpos($field, '_id')) {
            return 'deny';
        }

        return 'allow';
    }

    /**
     * 判断当前字段是否能显示
     * @param $field
     * @return string
     */
    public function checkFieldShow($field)
    {
        if (in_array($field, ['json', 'password'])) {
            return 'no';
        }

        return 'yes';
    }


    /**
     * 判断当前字段是否能排序
     * @param $field
     * @return string
     */
    public function checkFieldSort($field)
    {
        if (in_array($field, ['name', 'code', 'attribute_id', 'start_time', 'end_time', 'type', 'created_by', 'created', 'project_id', 'category_id', 'step_category_id'])) {
            return 'allow';
        }


        return 'deny';
    }


    /**
     * 判断当前字段是否能分组
     * @param $field
     * @return string
     */
    public function checkFieldGroup($field)
    {
        if (strpos($field, '_id')) {
            return 'allow';
        }

        return 'deny';
    }

    /**
     * 判断当前字段是否能过滤
     * @param $field
     * @return string
     */
    public function checkFieldFilter($field)
    {
        if (in_array($field, ['id', 'uuid', 'json', 'config', 'param', 'admin_password', 'node_config'])) {
            return 'deny';
        }

        return 'allow';
    }

    /**
     * 判断当前字段是否能过滤
     * @param $field
     * @return string
     */
    public function checkFieldPrimaryKey($field)
    {
        if ($field === 'id') {
            return 'yes';
        }

        return 'no';
    }

    /**
     * 判断当前字段是否能过滤
     * @param $field
     * @return string
     */
    public function checkFieldForeignKey($field)
    {
        if (strpos($field, '_id')) {
            return 'yes';
        }

        return 'no';
    }


    /**
     * 生成字段配置
     * @param $modelName
     * @param $realName
     * @param $moduleID
     * @param $field
     * @param $dataSource
     * @param $type
     * @return array
     */
    public function generateFieldConfig($modelName, $realName, $moduleID, $field, $dataSource, $type)
    {
        $fieldConfig = [
            "id" => 0, // 字段id, 固定字段是0，自定义字段是注册的id值
            "field" => $field, // 字段名
            "type" => $type, //字段类型
            "field_type" => "custom", //字段类型 built_in：固定字段，custom：自定义字段
            "disabled" => "no", // 是否禁用（yes, no）
            "require" => $this->checkFieldRequire($field), // 是否必须（yes, no）
            "table" => $modelName, // 所属表名
            "module_code" => $realName, // 所属模块名
            "module_id" => $moduleID, // 模块id
            "lang" => strtoupper($field), // 语言包KEY
            "editor" => "select", // 编辑器类型 下拉框
            "edit" => $this->checkFieldEdit($field), // 是否可以编辑（allow, deny）
            "show" => $this->checkFieldShow($field), // 是否在前台显示 （yes, no）
            "sort" => $this->checkFieldSort($field), // 是否可以排序（allow, deny）
            "group" => $this->checkFieldGroup($field), // 是否可以分组
            "group_name" => "", // 分组显示名称
            "filter" => $this->checkFieldFilter($field), // 是否可以过滤（allow, deny）
            "multiple" => "no", // 是否可以多选（yes, no）
            "format" => [], // 格式化配置
            "validate" => "", // 验证方法
            "mask" => "", // 掩码配置
            "is_primary_key" => $this->checkFieldPrimaryKey($field), // 是否是主键（yes, no）
            "is_foreign_key" => $this->checkFieldForeignKey($field), // 是否是外键（yes, no）
            "placeholder" => "no", // 输入框占位文本 （yes, no）
            "show_word_limit" => "no", // 是否显示输入字数统计 （yes, no）
            "autocomplete" => "no", // 是否自动补全 （yes, no）
            "value_icon" => "", // 值图标
            "label_icon" => "", // 文本图标
            "label_width" => 0, // 文本宽度
            "value_width" => 0, //  值宽度
            "is_label" => "no",  //  是否显示文本 （yes, no）
            "default_value" => "", // 默认值
            "data_source" => $dataSource
        ];

        return $fieldConfig;
    }

    /**
     * _ 名称转驼峰
     * @param $unCamelizeWords
     * @param string $separator
     * @return mixed
     */
    public function camelize($unCamelizeWords, $separator = '_')
    {
        $unCamelizeWords = $separator . str_replace($separator, " ", strtolower($unCamelizeWords));
        return str_replace(" ", "", ucwords(ltrim($unCamelizeWords, $separator)));
    }

    /**
     * Change Method.
     *
     * Write your reversible migrations using this method.
     *
     * More information on writing migrations is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
     *
     * The following commands can be used in this method and Phinx will
     * automatically reverse them when rolling back:
     *
     *    createTable
     *    renameTable
     *    addColumn
     *    renameColumn
     *    addIndex
     *    addForeignKey
     *
     * Remember to call "create()" or "update()" and NOT "save()" when working
     * with the Table class.
     */

    /**
     * Migrate Up.
     * @throws Exception
     */
    public function change()
    {
        $moduleMap = $this->getAllModuleData();

        // 添加自定义字段
        $needAddCustomFieldsModuleList = [
            'user_authentication' => [
                'table' => 'tenant_authentication',
                'relation' => [
                    [
                        'field' => 'media_front_of_id', // 法人身份证正面
                        'module' => 'media',
                        'type' => 'has_one'
                    ],
                    [
                        'field' => 'media_reverse_of_id', // 法人身份证反面
                        'module' => 'media',
                        'type' => 'has_one'
                    ],
                ]
            ]
        ];

        $rows = [];
        // 组装要新增的自定义字段
        foreach ($needAddCustomFieldsModuleList as $module => $moduleParam) {

            $table = $moduleParam['table'];
            $fieldData = [
                'is_horizontal' => 1,
                'module_id' => $moduleMap[$module]['id'],
                'type' => 'custom',
                'table' => $table,
                'uuid' => Webpatser\Uuid\Uuid::generate()->string
            ];
            $modelName = $this->camelize($table);

            foreach ($moduleParam['relation'] as $relationData) {
                $field = $relationData['field'];
                $relationModule = $relationData['module'];
                $relationType = $relationData['type'];

                $dataSource = [ // 数据源
                    "type" => "api", // 数据源类型，fixed 固定 , api 动态
                    "data" => [$relationModule], // 数据源，静态直接配置，动态是一个字符串标识
                    "src_module_id" => $moduleMap[$module]['id'],
                    "dst_module_id" => $moduleMap[$relationModule]['id'],
                    "relation_type" => $relationType
                ];

                $fieldConfig = $this->generateFieldConfig($modelName, $module, $moduleMap[$module]['id'], $field, $dataSource, 'horizontal_relation');
                $fieldData['config'] = json_encode($fieldConfig);
                $rows[] = $fieldData;
            }
        }

        // 写入字段数据表
        $this->table('field')->insert($rows)->save();
    }

}
